package bullwhipeffect;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import bullwhipeffect.GenericSupplyChainAgent;

import repast.simphony.context.Context;
import repast.simphony.dataLoader.ContextBuilder;
import repast.simphony.engine.environment.RunEnvironment;
import repast.simphony.parameter.Parameters;

public class AgentBuilder implements ContextBuilder<GenericSupplyChainAgent> {
	private Integer rawMaterialSupplierInterval;
	private Integer manufacturerInterval;
	private Integer wholesalerInterval;
	private Integer retailerInterval;
	
	public Context<GenericSupplyChainAgent> build(Context<GenericSupplyChainAgent> context) {
		Parameters parameters = RunEnvironment.getInstance().getParameters();
		String sourceFile = parameters.getValueAsString("initializationsourcefile");
		
		this.rawMaterialSupplierInterval = (Integer) parameters.getValue("rawMaterialSupplierInterval");
		this.manufacturerInterval = (Integer) parameters.getValue("manufacturerInterval");
		this.wholesalerInterval = (Integer) parameters.getValue("wholesalerInterval");
		this.retailerInterval = (Integer) parameters.getValue("retailerInterval");
		
		System.out.println("Adding agents to context: " + context.getId());
		System.out.println("Source file: " + sourceFile);
		this.buildAgentsFromSourceFile(sourceFile, context);
		
		return context;
	}

	private void buildAgentsFromSourceFile(String sourceFile, Context<GenericSupplyChainAgent> context){
		BufferedReader reader;
		String numAgentsLine;
		String numAgents[];
		int numSuppliers, numManufacturers, numWholesalers, numRetailers;
		
		try {
			reader = new BufferedReader(new FileReader(sourceFile));
			numAgentsLine = reader.readLine();
			numAgents = numAgentsLine.split(", ");
			numSuppliers = Integer.parseInt(numAgents[0]);
			numManufacturers = Integer.parseInt(numAgents[1]);
			numWholesalers = Integer.parseInt(numAgents[2]);
			numRetailers = Integer.parseInt(numAgents[3]);
			
			for (int i = 0; i < numSuppliers; i++){
				String properties = reader.readLine();
				GenericSupplyChainAgent agent = new GenericSupplyChainAgent();
				
				agent = this.loadGenericSupplyChainAgent(properties, agent, this.rawMaterialSupplierInterval);
				System.out.println("Adding agent: " + agent.getName());
				context.add(agent);
			}
			
			for (int i = 0; i < numManufacturers; i++){
				String properties = reader.readLine();
				GenericSupplyChainAgent agent = new GenericSupplyChainAgent();
				
				agent = this.loadGenericSupplyChainAgent(properties, agent, this.manufacturerInterval);
				System.out.println("Adding agent: " + agent.getName());
				context.add(agent);
			}
			
			for (int i = 0; i < numWholesalers; i++){
				String properties = reader.readLine();
				GenericSupplyChainAgent agent = new GenericSupplyChainAgent();
				
				agent = this.loadGenericSupplyChainAgent(properties, agent, this.wholesalerInterval);
				System.out.println("Adding agent: " + agent.getName());
				context.add(agent);
			}
			
			for (int i = 0; i < numRetailers; i++){
				String properties = reader.readLine();
				GenericSupplyChainAgent agent = new GenericSupplyChainAgent();
				
				agent = this.loadGenericSupplyChainAgent(properties, agent, this.retailerInterval);
				System.out.println("Adding agent: " + agent.getName());
				context.add(agent);
			}
		} catch (FileNotFoundException e) {
			System.out.println("An exception has been thrown while building the model: ");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("An exception has been thrown while reading the file: ");
			e.printStackTrace();
		}
	}
	
	private GenericSupplyChainAgent loadGenericSupplyChainAgent(String properties, GenericSupplyChainAgent agent, Integer repeatInterval){
		String[] arrayProperties = properties.split(", ");
		
		agent.setName(arrayProperties[0]);
		agent.setHoldingCost(Long.parseLong(arrayProperties[1]));
		agent.setShortageCost(Long.parseLong(arrayProperties[2]));
		agent.setOrderingCost(Long.parseLong(arrayProperties[3]));
		agent.setTransportationCost(Long.parseLong(arrayProperties[4]));
		agent.setProductionCost(Long.parseLong(arrayProperties[5]));
		agent.setMaximumInventoryLevel(Long.parseLong(arrayProperties[6]));
		agent.setProductionRate(Long.parseLong(arrayProperties[7]));
		agent.setLeadTime(Long.parseLong(arrayProperties[8]));
		agent.setInventoryLevel(0);
		//agent.setRepeatInterval(repeatInterval);
		
		return agent;
	}
}